package org.example.lethear.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.lethear.dto.common.PageResult;
import org.example.lethear.dto.post.*;
import org.example.lethear.entity.*;
import org.example.lethear.exception.BusinessException;
import org.example.lethear.exception.ForbiddenException;
import org.example.lethear.exception.ResourceNotFoundException;
import org.example.lethear.repository.*;
import org.example.lethear.utils.SecurityUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 帖子管理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PostService {
    
    private final PostRepository postRepository;
    private final UserRepository userRepository;
    private final CategoryRepository categoryRepository;
    private final LikeRepository likeRepository;
    private final CommentRepository commentRepository;
    
    /**
     * 创建帖子
     */
    @Transactional
    public PostDTO createPost(PostCreateRequest request) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 检查分类是否存在
        Category category = categoryRepository.findById(request.getCategoryId())
                .orElseThrow(() -> new ResourceNotFoundException("分类不存在"));
        
        // 创建帖子（只使用Post实体中实际存在的字段）
        Post post = new Post();
        post.setUserId(currentUserId);
        post.setCategoryId(request.getCategoryId());
        post.setTitle(request.getTitle());
        post.setContent(request.getContent());
        post.setSummary(request.getSummary());
        post.setStatus(request.getStatus());
        post.setIsTop(request.getIsTop() ? 1 : 0);
        post.setViewCount(0);
        post.setCommentCount(0);
        post.setLikeCount(0);
        
        post = postRepository.save(post);
        
        log.info("帖子创建成功: {} by {}", post.getTitle(), currentUserId);
        
        return convertToPostDTO(post);
    }
    
    /**
     * 更新帖子
     */
    @Transactional
    public PostDTO updatePost(Long postId, PostUpdateRequest request) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 检查权限
        if (!post.getUserId().equals(currentUserId) && !SecurityUtils.isAdmin()) {
            throw new ForbiddenException("无权限修改此帖子");
        }
        
        // 更新字段（只更新Post实体中存在的字段）
        if (StringUtils.hasText(request.getTitle())) {
            post.setTitle(request.getTitle());
        }
        
        if (StringUtils.hasText(request.getContent())) {
            post.setContent(request.getContent());
        }
        
        if (StringUtils.hasText(request.getSummary())) {
            post.setSummary(request.getSummary());
        }
        
        if (request.getCategoryId() != null) {
            // 检查分类是否存在
            categoryRepository.findById(request.getCategoryId())
                    .orElseThrow(() -> new ResourceNotFoundException("分类不存在"));
            post.setCategoryId(request.getCategoryId());
        }
        
        if (request.getStatus() != null) {
            post.setStatus(request.getStatus());
        }
        
        if (request.getIsTop() != null) {
            post.setIsTop(request.getIsTop() ? 1 : 0);
        }
        
        post = postRepository.save(post);
        
        log.info("帖子更新成功: {} by {}", post.getTitle(), currentUserId);
        
        return convertToPostDTO(post);
    }
    
    /**
     * 删除帖子
     */
    @Transactional
    public void deletePost(Long postId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 检查权限
        if (!post.getUserId().equals(currentUserId) && !SecurityUtils.isAdmin()) {
            throw new ForbiddenException("无权限删除此帖子");
        }
        
        postRepository.delete(post);
        
        log.info("帖子删除成功: {} by {}", post.getTitle(), currentUserId);
    }
    
    /**
     * 获取帖子详情
     */
    @Transactional
    public PostDTO getPostById(Long postId) {
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 增加浏览量
        post.incrementViewCount();
        postRepository.save(post);
        
        return convertToPostDTO(post);
    }
    
    /**
     * 查询帖子列表
     */
    public PageResult<PostDTO> getPosts(PostQueryRequest request) {
        // 构建排序
        Sort sort = buildSort(request.getSortBy(), request.getSortOrder());
        Pageable pageable = PageRequest.of(request.getPage() - 1, request.getSize(), sort);
        
        // 根据条件查询
        Page<Post> postPage;
        
        if (StringUtils.hasText(request.getKeyword())) {
            // 关键词搜索
        if (request.getCategoryId() != null) {
                // 分类 + 搜索
                postPage = postRepository.searchPostsInCategory(request.getKeyword(), request.getCategoryId(), pageable);
            } else if (request.getAuthorId() != null) {
                // 作者 + 搜索
                postPage = postRepository.searchPostsByAuthor(request.getKeyword(), request.getAuthorId(), pageable);
            } else {
                // 仅搜索
                postPage = postRepository.searchPosts(request.getKeyword(), pageable);
            }
        } else if (request.getCategoryId() != null) {
            // 按分类查询
            if (request.getStatus() != null) {
                postPage = postRepository.findByCategoryIdAndStatus(request.getCategoryId(), request.getStatus(), pageable);
            } else {
                postPage = postRepository.findByCategoryIdAndStatus(request.getCategoryId(), 1, pageable);
            }
        } else if (request.getAuthorId() != null) {
            // 按作者查询
            if (request.getStatus() != null) {
                postPage = postRepository.findByUserIdAndStatus(request.getAuthorId(), request.getStatus(), pageable);
            } else {
                postPage = postRepository.findByUserIdAndStatus(request.getAuthorId(), 1, pageable);
            }
        } else if (request.getStatus() != null) {
            // 按状态查询
            postPage = postRepository.findByStatus(request.getStatus(), pageable);
        } else {
            // 查询所有已发布的帖子
            postPage = postRepository.findByStatus(1, pageable);
        }
        
        List<PostDTO> postDTOs = postPage.getContent().stream()
                .map(this::convertToPostDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(postDTOs, postPage.getTotalElements(), request.getPage(), request.getSize());
    }
    
    /**
     * 点赞帖子
     */
    @Transactional
    public void likePost(Long postId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 检查是否已经点赞
        boolean alreadyLiked = likeRepository.existsByUserIdAndTargetIdAndTargetType(
                currentUserId, postId, Like.TYPE_POST);
        if (alreadyLiked) {
            throw new BusinessException("已经点赞过了");
        }
        
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 创建点赞记录
        Like like = new Like(currentUserId, postId, Like.TYPE_POST);
        likeRepository.save(like);
        
        // 增加点赞数
        post.incrementLikeCount();
        postRepository.save(post);
        
        log.info("帖子点赞成功: {} by {}", postId, currentUserId);
    }
    
    /**
     * 取消点赞帖子
     */
    @Transactional
    public void unlikePost(Long postId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 检查是否已点赞
        Like like = likeRepository.findByUserIdAndTargetIdAndTargetType(
                currentUserId, postId, Like.TYPE_POST)
                .orElseThrow(() -> new BusinessException("尚未点赞"));
        
        Post post = postRepository.findById(postId)
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 删除点赞记录
        likeRepository.delete(like);
        
        // 减少点赞数
        post.decrementLikeCount();
        postRepository.save(post);
        
        log.info("取消帖子点赞成功: {} by {}", postId, currentUserId);
    }
    
    /**
     * 获取热门帖子
     */
    public PageResult<PostDTO> getHotPosts(int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, 
                Sort.by("likeCount").descending()
                        .and(Sort.by("viewCount")).descending()
                        .and(Sort.by("createTime")).descending());
        
        Page<Post> postPage = postRepository.findByStatus(1, pageable);
        
        List<PostDTO> postDTOs = postPage.getContent().stream()
                .map(this::convertToPostDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(postDTOs, postPage.getTotalElements(), page, size);
    }
    
    /**
     * 构建排序
     */
    private Sort buildSort(String sortBy, String sortOrder) {
        Sort.Direction direction = "ASC".equalsIgnoreCase(sortOrder) ? 
                Sort.Direction.ASC : Sort.Direction.DESC;
        
        return switch (sortBy.toLowerCase()) {
            case "viewcount" -> Sort.by(direction, "viewCount");
            case "likecount" -> Sort.by(direction, "likeCount");
            case "commentcount" -> Sort.by(direction, "commentCount");
            case "createdat" -> Sort.by(direction, "createTime");
            case "createtime" -> Sort.by(direction, "createTime");
            default -> Sort.by(direction, "createTime");
        };
    }
    
    /**
     * 转换Post实体为PostDTO（简化版本）
     */
    private PostDTO convertToPostDTO(Post post) {
        PostDTO.PostDTOBuilder builder = PostDTO.builder()
                .id(post.getId())
                .title(post.getTitle())
                .content(post.getContent())
                .summary(post.getSummary())
                .status(post.getStatus())
                .isTop(post.isTopPost())
                .allowComment(true) // 默认允许评论
                .priority(0) // 默认优先级
                .tags(java.util.Arrays.asList()) // 暂时设置为空列表，后续可以添加标签功能
                .viewCount(post.getViewCount().longValue())
                .commentCount(post.getCommentCount().longValue())
                .likeCount(post.getLikeCount().longValue())
                .createdAt(post.getCreateTime())
                .updatedAt(post.getUpdateTime());
        
        // 作者信息
        userRepository.findById(post.getUserId()).ifPresent(user -> {
            PostDTO.AuthorInfo authorInfo = PostDTO.AuthorInfo.builder()
                    .id(user.getId())
                    .username(user.getUsername())
                    .nickname(user.getProfile() != null ? user.getProfile().getNickname() : null)
                    .avatar(user.getAvatar())
                    .build();
            builder.author(authorInfo);
        });
        
        // 分类信息
        categoryRepository.findById(post.getCategoryId()).ifPresent(category -> {
            PostDTO.CategoryInfo categoryInfo = PostDTO.CategoryInfo.builder()
                    .id(category.getId())
                    .name(category.getName())
                    .description(category.getDescription())
                    // 注意：Category实体中可能没有icon和color字段，暂时设为null
                    .icon(null)
                    .color(null)
                    .build();
            builder.category(categoryInfo);
        });
        
        // 检查当前用户是否已点赞
        Long currentUserId = SecurityUtils.getCurrentUserId();
        boolean isLiked = false;
        if (currentUserId != null) {
            isLiked = likeRepository.existsByUserIdAndTargetIdAndTargetType(
                    currentUserId, post.getId(), Like.TYPE_POST);
        }
        builder.isLiked(isLiked);
        
        return builder.build();
    }
} 